/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Engine.

    Maxsi Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiEngineContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiEngineContributors.h. For more information please see
	MaxsiEngineContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiEngine.dll
	A linkable version of Maxsi Engine

	MaxsiString.h
	Functions for easier string handling

****************************************************************************/
#ifndef MaxsiString_h
#define MaxsiString_h

#include <string>
#include "MaxsiEngine.h"

namespace MaxsiEngine
{
	
	// Maxsi String

	#define MESTRA char
	#define MESTRAL __int16 // Twice the size of MESTRA
	#define MESTRW wchar_t
	#define MESTRWL __int32 // Twice the size of MESTRW
	#define MESTRMBS MESTRW
	#define MESTRMBSL MESTRWL // Twice the size of MESTRMBS
	#define MESTRNMBS MESTRA
	#define MESTRNMBSL MESTRAL // Twice the size of MESTRNMBS

	#ifdef ME_USE_MULTIBYTE_STRING

		#define	MESTR MESTRMBS
		#define MESTRL MESTRMBSL // Twice the size of MESTR
		#define	MESTRLEN(string)	wcslen(string)
		#define	MESTRCMP(string,string2)	wcscmp(string,string2)
		#define	MESTRICMP(string,string2)	_wcsicmp(string,string2)
		#define	MESTRNCMP(string,string2,count)	wcsncmp(string,string2,count)
		#define	MESTRNICMP(string,string2,count)	_wcsnicmp(string,string2,count)
		#define	MESTRSIZE(string)	(sizeof(MESTR)*wcslen(string))
		#define MESTRCPY(dest, len, src) wcscpy_s(dest, len, src)

		// Converts the MESTR to a pointer with the address of the string. Call MESTRUP() when done with it.
		#define MESTRP(string) (char*)string

		// Converts the MESTR to a pointer to a wide char version of the string. Call MESTRUWP() when done with it.
		#define MESTRWP(string) (char*)string 
		
		// Converts the MESTR to a pointer to a ascii version of the string. Call MESTRUAP() when done with it.
		#define MESTRAP(string) WCHAR2CHAR(string)

		#define MESTRUP(string) // call when done with the return value of MESTRP()
		#define MESTRUWP(string) // call when done with the return value of MESTRWP()
		#define MESTRUAP(string) delete[] string // call when done with the return value of MESTRAP()

		#define	_MESTR(x) L ## x // Lets not hardcode strings any longer, but instead use a string table loaded from a file to aid with localisation.
		#define MESTRCAT(Dest, Size, Source) wcscat_s(Dest, Size, Source)
		#define MESTRITOA(Val, Dest, Size, Radix) _itow_s(Val, Dest, Size, Radix)
		#define MESTRITOA32(Val, Dest, Size, Radix) _itow_s(Val, Dest, Size, Radix)
		#define MESTRITOA64(Val, Dest, Size, Radix) _i64tow_s(Val, Dest, Size, Radix)
		#define MESTRUITOA(Val, Dest, Size, Radix) _ui64tow_s((unsigned __int64)Val, Dest, Size, Radix)
		#define MESTRUITOA32(Val, Dest, Size, Radix) _ui64tow_s((unsigned __int64)Val, Dest, Size, Radix)
		#define MESTRUITOA64(Val, Dest, Size, Radix) _ui64tow_s((unsigned __int64)Val, Dest, Size, Radix)
	
		#define MESTR2WCHAR(String) BuildString(1, String)
		#define MESTR2CHAR(String) WCHAR2CHAR(String)

	#else

		#define	MESTR				MESTRNMBS
		#define MESTRL MESTRNMBSL // Twice the size of MESTR
		#define	MESTRLEN(string)	strlen(string)
		#define	MESTRCMP(string,string2)	strcmp(string,string2)
		#define	MESTRICMP(string,string2)	_stricmp(string,string2)
		#define	MESTRNCMP(string,string2,count)	strncmp(string,string2,count)
		#define	MESTRNICMP(string,string2,count)	_strnicmp(string,string2,count)
		#define	MESTRSIZE(string)	strlen(string)
		#define MESTRCPY(dest, len, src) strcpy_s(dest, len, src)

		// Converts the MESTR to a pointer with the address of the string. Call MESTRUP() when done with it.
		#define MESTRP(string) (char*)string

		// Converts the MESTR to a pointer to a wide char version of the string. Call MESTRUWP() when done with it.
		#define MESTRWP(string) CHAR2WCHAR(string)
		
		// Converts the MESTR to a pointer to a ascii version of the string. Call MESTRUAP() when done with it.
		#define MESTRAP(string) (char*)string 

		#define MESTRUP(string) // call when done with the return value of MESTRP()
		#define MESTRUWP(string) delete[] string // call when done with the return value of MESTRWP()
		#define MESTRUAP(string) // call when done with the return value of MESTRAP()

		#define	_MESTR(x) x
		#define MESTRCAT(Dest, Size, Source) strcat_s(Dest, Size, Source)
		#define MESTRITOA(Val, Dest, Size, Radix) _itoa_s(Val, Dest, Size, Radix)
		#define MESTRITOA32(Val, Dest, Size, Radix) _itoa_s(Val, Dest, Size, Radix)
		#define MESTRITOA64(Val, Dest, Size, Radix) _i64toa_s(Val, Dest, Size, Radix)
		#define MESTRUITOA(Val, Dest, Size, Radix) _ui64toa_s((unsigned __int64)Val, Dest, Size, Radix)
		#define MESTRUITOA32(Val, Dest, Size, Radix) _ui64toa_s((unsigned __int64)Val, Dest, Size, Radix)
		#define MESTRUITOA64(Val, Dest, Size, Radix) _ui64toa_s((unsigned __int64)Val, Dest, Size, Radix)

		#define MESTR2WCHAR(String) CHAR2WCHAR(String)
		#define MESTR2CHAR(String) BuildString(1, String)

	#endif


	class AUTODELETE { public: AUTODELETE(char* Buffer) : m_Buffer(Buffer) { } ~AUTODELETE() { delete m_Buffer; } private: char* m_Buffer; }; 
	class AUTODELETEAR { public: AUTODELETEAR(char* Buffer) : m_Buffer(Buffer) { } ~AUTODELETEAR() { delete[] m_Buffer; } private: char* m_Buffer; }; 

	LINKCPP	size_t	__forceinline SkipWhiteSpace	(MESTR* Buffer);
	LINKCPP	size_t	__forceinline SkipWhiteSpace	(MESTR* Buffer, size_t BufferLen);
	LINKCPP	size_t	__forceinline NextWhiteSpace	(MESTR* Buffer);
	LINKCPP	size_t	__forceinline NextWhiteSpace	(MESTR* Buffer, size_t BufferLen);
	LINKCPP	size_t	__forceinline NextLine			(MESTR* Buffer);
	LINKCPP	size_t	__forceinline NextLine			(MESTR* Buffer, size_t BufferLen);
	LINK	MESTR*	EvaluateQuote	(MESTR* Buffer);
	LINK	size_t	FindChar		(MESTR* Buffer, MESTR CharToFind, size_t BufferLen);
	LINK	size_t	FindCharPrev	(MESTR* Buffer, MESTR CharToFind, size_t Begin);
	LINK	size_t	FindString		(MESTR* String1, MESTR* String2);
	LINK	size_t	FindStringEx	(MESTR* String1, size_t String1Len, MESTR* String2, size_t String2Len);
	LINK	bool	str_replace		(MESTR* input, MESTR* find, MESTR* replace);
	LINK	bool	buf_replace		(MESTR* input,size_t input_Len, MESTR* find, size_t find_Len, MESTR* replace, size_t replace_Len);
	LINK	MESTR*	StringReplace	(MESTR* Search, MESTR* Insert, MESTR* Haystack);
	LINK	MESTR*	SubString		(size_t Start, size_t Length, MESTR* ExtractFrom);
	LINK	char	FromHEXA		(char Hex);
	LINK	wchar_t	FromHEXW		(wchar_t Hex);
	LINK	MESTR	FromHEXM		(MESTR Hex);
	LINK	short	ToHEXA			(char In);
	LINK	int		ToHEXW			(wchar_t In);
	LINK	MESTRL	ToHEXM			(MESTR In);	
	LINK	bool	DecodeURL		(char* URL);
	LINK	char*	EncodeURL		(char* URL);	
	LINK	MESTR*	EncodeFileName	(MESTR* FileName);
	LINK	bool	ShouldCharBeEncodedURL		(MESTR In);
	LINK	bool	ShouldCharBeEncodedFileName	(MESTR In);
	//LINK	bool	IsASCII			(char* Input, size_t ClaimedLenght);
	LINKCPP	MESTR*	BuildString		(unsigned int NumParameters, ...);
	LINK	size_t	strlen_s		(MESTR* String, size_t MaxLen);
	//LINK	LPWSTR	ASCII2UNICODE	(char* Text);
	LINK	size_t	HEXTOI			(MESTR* Text);

	LINK	MESTR*	IToA		(int				In);
	LINK	MESTR*	UIToA		(unsigned	int		In);
	LINK	MESTR*	IToA64		(			__int64	In);
	LINK	MESTR*	UIToA64		(unsigned	__int64	In);
	LINK	MESTR*	DToA		(			double	In, int Digits, int StringLen = _CVTBUFSIZE);

	LINK	char*		WCHAR2CHAR(wchar_t* Input);
	LINK	wchar_t*	CHAR2WCHAR(char* Input);
}
#endif